package ktvutil

import (
	"encoding/base64"
	"fmt"
	"github.com/astaxie/beego/httplib"
	"ktvserver/config"
	"log"
	"net"
	"net/http"
	"strings"
	"time"
)

var (
	// 网络地址缓存
	mapIP2Address map[string]string
)

func init() {
	mapIP2Address = make(map[string]string)

	go DdnsRoutine()
}

// 设置动态域名参数
func SetDDnsParam(name string, key string, enalble bool) {

	name = strings.TrimSpace(name)
	key = strings.TrimSpace(key)

	config.SetValue("ddns_name", name)
	config.SetValue("ddns_key", key)

	if enalble {
		config.SetValue("ddns_enable", "1")
	} else {
		config.SetValue("ddns_enable", "0")
	}

	config.SaveConfig()

}

// 获取动态域名参数
func GetDDnsParam() (name string, key string, enable bool) {
	name = config.GetValue("ddns_name", "")
	key = config.GetValue("ddns_key", "")

	name = strings.TrimSpace(name)
	key = strings.TrimSpace(key)

	s := config.GetValue("ddns_enable", "")
	if s == "1" {
		enable = true
	} else {
		enable = false
	}

	return
}

// 动态域名的实现
func getRequestString(name string, key string, myip string) string {

	strContent := ""

	strContent = fmt.Sprintf("GET /nic/update?hostname=%s&myip=%s HTTP/1.1\r\n", name, myip)

	strContent += "Host: dyn.dns.he.net\r\n"
	strContent += "Accept: */*\r\n"
	strContent += "Cache-Control: max-age=0\r\n"

	// 认证信息
	// Authorization: Basic ZHluLnl3cC5tZToxMjM0NTY3ODk=
	strEncodeFrom := name + ":" + key
	strEncodeResult := base64.StdEncoding.EncodeToString([]byte(strEncodeFrom))
	strContent += fmt.Sprintf("Authorization: Basic %s\r\n", strEncodeResult)

	strContent += "User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET4.0C; .NET4.0E)\r\n"
	strContent += "Connection: Close\r\n"
	strContent += "\r\n"

	return strContent
}

// 更新域名记录
func UpdateDomainRecord(name string, key string, myip string) bool {

	if len(myip) == 0 {
		return false
	}

	// 解析地址
	remoteAddr, err1 := net.ResolveTCPAddr("tcp", "dyn.dns.he.net:80")
	if err1 != nil {
		return false
	}

	// 连接到he.net的服务器
	conn, err2 := net.DialTCP("tcp", nil, remoteAddr)
	if err2 != nil {
		log.Printf("err2=%v", err2)
		return false
	}

	defer conn.Close()

	strReq := getRequestString(name, key, myip)
	conn.Write([]byte(strReq))

	buf := make([]byte, 8092)
	conn.Read(buf)

	return true
}

//
func DdnsRoutine() {

	// 休眠
	time.Sleep(time.Second * 30)

	for {
		DDnsUpdate()
		time.Sleep(time.Second * 300)
	}

}

func DDnsUpdate() bool {

	// 获取互联网的地址
	myip := GetInternetAddress()
	if len(myip) == 0 {
		myip = GetInternetAddress()
	}

	// 没有连接到互联网
	if len(myip) == 0 {
		return false
	}

	// 获取动态域名的配置
	name, key, isEnable := GetDDnsParam()
	if isEnable != true || len(name) == 0 || len(key) == 0 {
		return false
	}

	// 获取就的记录
	oldip := GetHostAddress(name)
	if len(oldip) == 0 {
		oldip = GetHostAddress(name)
	}

	log.Printf("name=%s, myip=%s, oldip=%s", name, myip, oldip)

	if oldip != myip {
		UpdateDomainRecord(name, key, myip)
	}

	return true
}

// 获取网络地址
// http://ip.chinaz.com/?IP=113.110.141.215
func GetLocationEx(ip string) string {
	strLocation := ""
	req := httplib.Get("http://my.chinaz.com/_topbar.aspx?proxy=/httpproxy.aspx")

	resp, err := req.SendOut()
	if err != nil {
		return strLocation
	}

	myCookies := resp.Cookies()

	reqPost := httplib.Post("http://ip.chinaz.com/")
	reqPost.Param("ip", ip)

	for _, c := range myCookies {
		cookie := &http.Cookie{}
		cookie.Name = c.Name
		cookie.Value = c.Value
		reqPost.SetCookie(cookie)
	}

	content, err := reqPost.String()
	if err != nil {
		// error
	}
	//fmt.Println(content)

	key1 := "<p class=\"WhwtdWrap bor-b1s col-gray03\">"
	key2 := "</p>"

	pos1 := strings.Index(content, key1)
	if pos1 < 0 {
		//	fmt.Printf("content = %s\n", content)
		return strLocation
	}

	strResult := content[pos1+len(key1):]
	pos2 := strings.Index(strResult, key2)
	if pos2 < 0 {
		//fmt.Printf("strResult = %s\n", strResult)
		return strLocation
	}

	strIpContent := strResult[0:pos2]

	//	fmt.Printf("strIpcontent=%s\n", strIpContent)

	keyWord1 := "<span class=\"Whwtdhalf w50-0\">"
	keyWord2 := "</span>"

	posWord1 := strings.Index(strIpContent, keyWord1)
	if posWord1 < 0 {
		return strLocation
	}

	strResult1 := strIpContent[posWord1+len(keyWord1):]
	posWord2 := strings.Index(strResult1, keyWord2)
	if posWord2 < 0 {
		//	fmt.Printf("strResult1 = %s", strResult1)
		return strLocation
	}

	strLocation = strResult1[0:posWord2]
	strLocation = strings.Replace(strLocation, " ", "", -1)

	//fmt.Printf("%s", strLocation)

	return strLocation
}
